//2024.03.29 22:42 星期五 晴 小狗-56 以前认识 苏尘他们!
//2024.03.31 00:09 星期日 晴转雨 刚好在 最后一次 采桑叶的时候之后下的雨 第一次 四片 二级桑叶 后面又怕 全出来了 去采的 出来了 近35只 直接饿死一只
//2024.04.18 01:09 星期四 吕游说 之前 唯唯诺诺 那些小情绪 其实都是装的 现在 就是 开放起来！ 那就晚安~ :) 晚安吕游

/**
 * new promise 返回 暂且 好像 还不太会
 * 因为 new promise  是 直接运行的 结果
 */

// import { signAvanda } from '../../../components/aaanewApp/global/algo/avanda/main';
import {
  CaptureArray,
  ObjectOnlyPushSet,
  emptyClone,
  toStringTypeCheck,
  //   formatObj,
  //   getNum,
  settimeNth,
} from '../../../components/aaanewApp/global/global';
// import { funcAsync } from './functionAsync/functionAsync';

import { task } from './settleInfos/task';
import { prop } from './settleInfos/prop';
import { main } from './settleInfos/main';
import { groups } from './settleInfos/groups';
import { mixSettles } from '../avandaUnitObj/loadSettleInfo/loadSettleInfo';

if (window.settimeNth == undefined) {
  window.settimeNth = settimeNth;
}
/**
 * 不行了 太困了 2024.04.01 03:32 晴
 * @todo 想做一个 函数之间 能交流数据的
 */

// let splitStr = '_';

const data = 'data';
const $data = '$data';

/**
 * avanda 的 单元 object tostringType 名称
 */
const avandaStringTag = 'avandaTaskObject';

const settleInfos = 'settleInfos';

const limitDefine = 'descriptor';

const askForSettles = 'askForSettles';

const settleInfo = 'settleInfo';

const asyncProxy = 'asyncProxy';

const asyneDone = 'done';

/**
 * -- main tasksName 所有组件 名称集合
 */
const tasksName = 'tasksName';

/**
 * 不做处理 记录 avanda 的 关键 字符
 */
let withoutRecordArr = [undefined, 'main', 'groups'];

/**
 * 数据请求 任务表
 */
let asyncTask = { data: [] };

/**
 * 用户 记录的 名称 的 特定区块 加载
 */
let reoderSettlesInfo = mixSettles;
// import("./loadSettleInfo/loadSettleInfo").then((mod)=>{reoderSettlesInfo=mod["mixSettles"]});

/**
 * 当前
 * 用户实例 安装需求
 * 默认 --default
 */
let defaultSettlesArr;

/**
 * 请求区块
 * hot
 * 向 settleInfos 去 下载
 */
let downloadedSettleInfos = {
  data: ['task', 'prop', 'main', 'groups'],
  main,
  task,
  prop,
  groups,
};

class avandaTaskObj {
  get [Symbol.toStringTag]() {
    return avandaStringTag;
  }

  constructor(taskName, describe, resolve, useMode, groupto) {
    // 结构信息 如果 传入参数 第一个 为 对象 则 进行结构
    if (toStringTypeCheck(taskName, 'object')) {
      ({ taskName, describe, resolve, useMode, groupto } = taskName);
    }
    /**
     * 使用 用户 自定义 mod
     */
    changeLoadMod(useMode);

    /**
     * 增添 $data 索引组
     */
    this[$data] = [];

    /**
     * 增添 实例用户 data 索引组
     */
    this[data] = [];

    ObjectOnlyPushSet(this, 'name', taskName, $data);

    ObjectOnlyPushSet(this, 'describe', describe, $data);

    // 添加 外部 resolve 函数 在 加载完毕后 调用该函数
    pushResolveMagnet(this, resolve);

    /**
     * 放置 settle infos -- 相关 设置信息 的 结构
     */
    ObjectOnlyPushSet(this, settleInfos, { data: [] }, $data);

    // //   添加用户实例 扩展 功能
    // this.extendAvanda = extendAvanda;

    // //   添加用户实例 缩减 功能
    // this.shrinkAvanda = shrinkAvanda;

    /**
     * 安装 特定 设定函数
     */
    initAvandaObject(this);

    // 创建 初始化 main avanda
    if (
      window.Avanda == undefined &&
      withoutRecordArr.indexOf(taskName) == -1
    ) {
      window.Avanda = new avandaTaskObj({
        taskName: 'main',
        describe: 'main Avanda',
        useMode: 'main',
      });
    }
    // 创建 记录 group
    if (groupto != undefined) {
      // 初始 groups 架构
      if (window.Avanda['groups'] == undefined) {
        window.Avanda['groups'] = [];
      }
      // 自动 创立 对应 groups 信息
      if (window.Avanda['groups'].indexOf(groupto) == -1) {
        // 创建 对应 group avanda
        if (ObjectOnlyPushSet(window.Avanda, groupto, undefined, 'groups')) {
          window.Avanda[groupto] = new avandaTaskObj({
            taskName: groupto,
            describe: 'groups',
            useMode: 'groups',
            groupto,
          });
        }
      }
      if (taskName != groupto) {
        ObjectOnlyPushSet(window.Avanda[groupto], taskName, this, 'group');
      }
    }

    // 向  mian avanda 中 添加 命名的 avanda obj 数据 该信息
    else if (withoutRecordArr.indexOf(taskName) == -1) {
      if (!ObjectOnlyPushSet(window.Avanda, taskName, this, tasksName)) {
        console.log(`current TaskName  : ${taskName} is already recorded `);
      }
    }

    /**
     * 返回 默认 设置 模式
     */
    changeLoadMod('default');
  }
  extendAvanda = extendAvanda;
  shrinkAvanda = shrinkAvanda;
}

/**
 * 新初始化 avandaObj
 * @param {this} that 当前实例对象
 */
function initAvandaObject(that) {
  for (let i = 0; i < defaultSettlesArr.length; i++) {
    // 设置名称
    let settleName = defaultSettlesArr[i];
    unitsetSettle(that, settleName);
  }
}

// 单元添加 设置项 包括 前置 必要 设置
function unitsetSettle(that, settleName) {
  /**
   * async wait
   */
  that[asyncProxy][settleName] = 'wait';
  let settle = downloadedSettleInfos[settleName];
  if (downloadedSettleInfos[data].indexOf(settleName) > -1) {
    if (settle[askForSettles] != undefined) {
      if (toStringTypeCheck(settle[askForSettles], 'string')) {
        unitsetSettle(that, settle[askForSettles]);
      } else if (toStringTypeCheck(settle[askForSettles], 'array')) {
        for (const key of settle[askForSettles]) {
          unitsetSettle(that, key);
        }
      }
    }
    // console.log(settleName);
    /**
     * async done
     */
    that.extendAvanda(settleName, settle[settleInfo]);
    that[asyncProxy][settleName] = 'done';
  } else {
    import(`./settleInfos/${settleName}`).then((mod) => {
      console.log(mod);
      ObjectOnlyPushSet(downloadedSettleInfos, settleName, mod[settleName]);
      unitsetSettle(that, settleName);
    });
  }
}

/**
 * 检测 设置信息 是否有相同的命名 避免重复
 * @param {Object} that this 用户实例
 * @param {Object} settleInfo 设置信息集
 * @returns 如果 无重复 命名 返回 true 或者 提示 重复命名 的 props
 */
function askforArea(that, settleInfo) {
  let AskArea = CaptureArray(...settleInfo[data]);
  let returninf = true;
  //   console.log(AskArea);
  for (let i = 0; i < AskArea.length; i++) {
    if (that[$data].indexOf(AskArea[i]) > -1) {
      console.log('your extend prop is already over :' + AskArea[i]);
      returninf = false;
    }
  }
  return returninf;
}

/**
 * 将设置信息 添加到实例上
 * @param {Object} that this 用户实例
 * @param {Object} settleInfo 设置信息
 */
function defineProps(that, settleInfo) {
  // 单元 data 取值
  let key;

  // settleInfo 的 关键字 值 名称
  let val = 'value';

  for (let i = 0; i < settleInfo[data].length; i++) {
    key = settleInfo[data][i];
    if (settleInfo[key][limitDefine] == true) {
      // 删除 descriptor 标识符
      delete settleInfo[key][limitDefine];
      that[$data].push(key);
      Object.defineProperty(that, key, settleInfo[key]);
    } else {
      ObjectOnlyPushSet(that, key, settleInfo[key][val], $data);
    }
  }
}

/**
 * 将设置 信息 添加到实例上
 * @param {Object} that this 用户实例
 * @param {String} settleName 设置 系列名称
 * @param {Object} settleInfo 设置信息
 */
function defineSettle(that, settleName, settleInfo) {
  if (!ObjectOnlyPushSet(that[settleInfos], settleName, settleInfo[data])) {
    console.log('sorry we have recorded this setting infos :' + settleName);
  }
}

/**
 * 将常规信息 统一转换为 defineProperty 对象 格式
 * -
 *
 * 对 设置信息 进行特别填充 减少 手动重复 信息填写
 *
 * 因为 赋值 可能是个对象值 所以 需要 特别验证 以确定 时 进行 属性 的构造
 * 当内置 属性 有 descriptor:true 时 进行 特别补充
 * @param {Object} SettleInf 常规设置 settle inf 信息
 */
function formatSettleInf(SettleInf) {
  let key;
  let returninf = { data: [...SettleInf[data]] };
  for (let i = 0; i < SettleInf[data].length; i++) {
    key = SettleInf[data][i];
    let obj = {};
    if (SettleInf[key][limitDefine] == true) {
      for (const pro in SettleInf[key]) {
        // if (pro == limitDefine) {
        //   continue;
        // } else
        if (Object.hasOwnProperty.call(SettleInf[key], pro)) {
          obj[pro] = SettleInf[key][pro];
        }
      }
    } else {
      obj['value'] = SettleInf[key];
    }
    returninf[key] = obj;
  }
  return returninf;
}

/**
 * 扩增 avanda 内置 函数
 * -
 * @param {string} extendName 扩增项 的名称
 * @param {Object} settleInf 扩增函数 集
 * @example
 *  let a = {
    data: ['tasksName', 'sign_task', 'get_task'],
    tasksName: [],
    sign_obj,
    get_task,
  };
  this.extendAvanda('main', a);
 */
function extendAvanda(extendName, settleInf) {
  // 非强 添加
  if (this[settleInfos][data].indexOf(extendName) > -1) {
    return;
  }
  let getAreaPromise = askforArea(this, settleInf);
  if (!getAreaPromise) {
    return 0;
  }
  let formatSetInf = formatSettleInf(settleInf);
  defineProps(this, formatSetInf);
  defineSettle(this, extendName, formatSetInf);
}

/**
 * 缩减 avanda 设置 相关 函数
 * -
 * @param {String|Array} shrinkSettleName 绑定过的 设置 项 或 设置项 名称数组
 * @param {Array} onlyArr 自定义 删除项
 */
function shrinkAvanda(shrinkSettleName, onlyArr) {
  if (shrinkSettleName == undefined) {
    return;
  }
  if (toStringTypeCheck(shrinkSettleName, 'string')) {
    if (
      this[settleInfos][data].indexOf(shrinkSettleName) == -1 ||
      shrinkSettleName == data
    ) {
      return;
    }
    let propNameArr = [];
    if (onlyArr != undefined) {
      for (const i of onlyArr) {
        for (const j of this[settleInfos][shrinkSettleName]) {
          if (i == j) {
            if (propNameArr.indexOf(i) == -1) {
              propNameArr.push(i);
            }
          }
        }
      }
      if (propNameArr.length == 0) {
        // 复制 本
        propNameArr = emptyClone(this[settleInfos][shrinkSettleName]);
      }
    } else {
      // 复制 本
      propNameArr = emptyClone(this[settleInfos][shrinkSettleName]);
    }

    // 按需求删除 avanda 上的相关 信息
    deleteAvandaSettleProp(this, shrinkSettleName, propNameArr);
  } else if (toStringTypeCheck(shrinkSettleName, 'array')) {
    for (const i of shrinkSettleName) {
      shrinkAvanda.call(this, i, onlyArr);
    }
  }
}

/**
 * 按需 删除 对应函数 和 settleInfos 上的 记录 清理
 * -
 * @param {this} that this avanda 用户实例
 * @param {String} settleName 设置 元素 的名称
 * @param {String} propNameArr 设置 元素 的 相关 属性 名称
 */
function deleteAvandaSettleProp(that, settleName, propNameArr) {
  let prop_i;
  let data_prop_i;
  for (let i = 0; i < propNameArr.length; i++) {
    prop_i = that[settleInfos][settleName].indexOf(propNameArr[i]);

    // 清楚 设置信息 的 具体 函数名称
    that[settleInfos][settleName].splice(prop_i, 1);

    data_prop_i = that[$data].indexOf(propNameArr[i]);

    // 删除 实例 data 记录中的 信息
    if (data_prop_i > -1) {
      that[$data].splice(data_prop_i, 1);
    }

    // 删除 相关 函数
    delete that[propNameArr[i]];
  }
  if (that[settleInfos][settleName].length == 0) {
    let settlename_i = that[settleInfos][data].indexOf(settleName);
    that[settleInfos][data].splice(settlename_i, 1);
    delete that[settleInfos][settleName];
  }
}

/**
 * 立即 请求 设置 挂载
 * @param {this} that this avanda 用户实例
 * @param {String|Array} settleName 设置名称 允许名称数组 添加
 */
function askForSettle(that, settleName) {
  if (toStringTypeCheck(settleName, 'string')) {
    unitsetSettle(that, settleName);
  } else if (toStringTypeCheck(settleName, 'array')) {
    for (const key of settleName) {
      askForSettle(that, key);
    }
  }
}

// asyncTask.resolve=resolve

/**
 * 监听 asyncTask 对象 的 指定 函数
 * @param {this} that 监听对象
 * @param {String} prop 属性
 * @param {any} val 属性值
 * @returns
 */
function asyncSetFunc(that, prop, val) {
  if (!ObjectOnlyPushSet(that, prop, val)) {
    that[prop] = val;
  }

  if (val == asyneDone) {
    if (trustDone(that)) {
      if (toStringTypeCheck(that['resolve'], 'function')) {
        that['resolve']();
      }
    }
  }
  return true;
}

/**
 *
 * @param {Object} that asyncProxy proxy 的 reslove 对象
 * @param {Function} resolve promise 传递的 resolve 信息 函数
 */
function pushResolveMagnet(that, resolve) {
  if (ObjectOnlyPushSet(that, asyncProxy, undefined, $data)) {
    let asyncProxyObj = new Proxy(emptyClone(asyncTask), { set: asyncSetFunc });
    that[asyncProxy] = asyncProxyObj;
  }
  that[asyncProxy]['resolve'] = resolve;
}

/**
 * 检测 分支任务 是否 都已完成
 * @param {this} that 任务 完成情况链
 */
function trustDone(that) {
  let returninf = true;
  for (const key of that['data']) {
    if (key == 'resolve') {
      continue;
    }
    if (that[key] != asyneDone) {
      returninf = false;
      break;
    }
  }
  return returninf;
}

// let a = { data: [] };
// function donG() {
//   console.log('is Done');
// }
// pushResolveMagnet(a, donG);
// a[asyncProxy]['acv'] = '666';
// a[asyncProxy]['acv'] = 'done';

/**
 *
 * @param {String} key 特定 函数集 名称
 * @param {Array} val 对 特定函数组件 数组
 */
function extendOrderSettle(key, val) {
  if (!ObjectOnlyPushSet(reoderSettlesInfo, key, val)) {
    reoderSettlesInfo[key] = val;
  }
}

/**
 * 封启 绑定 reback
 */

// function bindRebackObj(that) {
//     let returninf
//     let rebackRules={
//         set:function (that,key,val) {

//         },get:function (that,key) {
//             if (histroyGet(that,key)) {
//                 that[historyObj][key][]
//             }
//         }
//     }
//     returninf=new Proxy(that,rebackRules)

// return returninf
// }

/**
 * 改变 和 添加自定义 mod
 * -
 * @param {String} modName 设置 avanda mod 装载信息
 * @param {Array} modsettles 自定义 安装的 程式
 */
function changeLoadMod(modName, modsettles) {
  if (modName == undefined) {
    modName = 'default';
  }
  if (modsettles != undefined) {
    if (!ObjectOnlyPushSet(reoderSettlesInfo, modName, modsettles)) {
      reoderSettlesInfo[modName] = modsettles;
    }
    // addSettleInf_to_loadSettleInfo_file();
    console.log(reoderSettlesInfo);
  }
  defaultSettlesArr = reoderSettlesInfo[modName];
}

// function addSettleInf_to_loadSettleInfo_file() {
//   const fs = require('fs');
// //   console.log(fs);
//   let content = `let mixSettles = ${String(reoderSettlesInfo)};

//   export { mixSettles };
//   `;

// writeFile(
//     '../avandaUnitObj/loadSettleInfo/loadSettleInfo.js',
//     content
//   );
// }

export {
  avandaTaskObj,
  askForSettle,
  extendOrderSettle,
  pushResolveMagnet,
  changeLoadMod,
};
// git commit -m "很高兴 这两天 都处理 了 一件事 先开始是添加 延时功能 后是 添加 扩充的 mindTask 函数 用于 临时 运行 新建函数--(这个可能 还要写 从哪儿到哪儿运行--fromto 以及 跳步运行--array) 日记 昨天 2024.04.30 01:32 我告诉了他 前因 我以为会怎样 但却石沉大海般 毫无音讯 而且 昨天 他的 云云 也走了 也没回我消息 弄得我像个小丑 但是 昨天 上午最后 好像听到了 要锻炼 嘎嘎猛 小八 (文件 原话 在 avandaUnitObj.js 末尾)"
// 哥 其实 在我高二的时候 就知道你了
// 那时是和朋友谈及到你 你的生平事迹 均一一实现 唯有最后一点 可能会有遗憾
// 在第一次遇见你时 就有种莫名的的熟悉感 而且散发着活力 那时好像还叫 吕漂亮 :) （男孩 取这名？ 不过 好像在哪儿听过 有点印象）
// 在第一次 知道你名字的时候 我心头微颤一下 欣喜若狂 心想：原来是你呀 吕游 185 18 嘎嘎猛 了我两年 别名吕漂亮 以后这些年 请多多指教啊 吕游 :)。
// 正如开头所说 哥们的生平事迹 在高二那年 我讲给了一位同学听
// 他说：不行 他那么脏你还要和他搞？ 直接远离不行？
// 我说：可能不太行 因为 我之后可能会缺失这段感情从而缺少关键零部件 导致人生失轨。
// 所以最后我争取到了 百分之九十九点九的拒绝 以及最希望的百分之零点一 在一起
// 但好像 事与愿违 前面所有的事都对的上 唯有 “一直在的 想看看在最后究竟会学到个什么人生哲理”这个有些遗憾
// 哥们 可能就是那 百分之九十九点九 那位不幸的人 哈哈

// 答应我 这段话 不要和任何人提及 永远！麻烦了 :)'

// git commit -m "2024.05.17 22:56 晴 晚上 吕游 邀请 小八 视频电话 晚上听见 苏尘 连电话 都不打 跟 温总很少打电话 更没有 视频电话 (跟你 有 鸡毛关系? 就因为 你知道 并目睹到结局? 那你的呢  还有 一次背叛 做好准备了吗? 感觉 好蠢 就为了 让他 当条狗？)     -- 晚上好 avanda :) 这些天 添加了 promise 功能 也就是说 在 加载完后 可以 调用 后续函数 但是 需要 之后 才能运行 此代码 要扩充时间线 ! 后续 可能还要添加时间线 功能函数组。 然后 现在 想到了 拖拽 组合 各组合信息 在元素内 在 window 记录下 弹出 功能页。"
